<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
</head>
<body>
    <canvas id="physicsCanvas" width="450" height="520"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // --- Parameters ---
        const origin = { x: 320, y: 450 };
        const ballCenter = { x: 150, y: 200 };
        const ballRadius = 20;

        // --- Clear Canvas ---
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // --- Draw Axes ---
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 2;
        ctx.font = '20px Times New Roman';

        // Ground line
        ctx.beginPath();
        ctx.moveTo(50, origin.y);
        ctx.lineTo(400, origin.y);
        ctx.stroke();

        // x-axis (vertical)
        ctx.beginPath();
        ctx.moveTo(origin.x, origin.y);
        ctx.lineTo(origin.x, 50);
        ctx.stroke();

        // Arrowhead for x-axis
        ctx.beginPath();
        ctx.moveTo(origin.x, 50);
        ctx.lineTo(origin.x - 6, 60);
        ctx.moveTo(origin.x, 50);
        ctx.lineTo(origin.x + 6, 60);
        ctx.stroke();

        // --- Draw Coiled Rope on Ground ---
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        const coilStartX = ballCenter.x - 45;
        const numCoils = 9;
        const coilWidth = 90 / numCoils;
        ctx.moveTo(coilStartX, origin.y);
        for (let i = 0; i < numCoils; i++) {
            const centerX = coilStartX + i * coilWidth + coilWidth / 2;
            ctx.arc(centerX, origin.y, coilWidth / 2, Math.PI, 0, false);
        }
        ctx.stroke();
        
        // --- Draw Ball ---
        ctx.beginPath();
        ctx.arc(ballCenter.x, ballCenter.y, ballRadius, 0, 2 * Math.PI);
        // Add a slight gradient for 3D effect
        const gradient = ctx.createRadialGradient(
            ballCenter.x - ballRadius * 0.3, 
            ballCenter.y - ballRadius * 0.3, 
            ballRadius * 0.1, 
            ballCenter.x, 
            ballCenter.y, 
            ballRadius
        );
        gradient.addColorStop(0, 'white');
        gradient.addColorStop(1, '#E0E0E0'); // Light gray
        ctx.fillStyle = gradient;
        ctx.fill();
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;
        ctx.stroke();

        // --- Draw Hanging Rope/Chain ---
        ctx.lineWidth = 1.5;
        const chainLinkHeight = 11;
        const chainLinkWidth = 9;
        // The chain starts from the bottom of the ball and goes to the ground
        for (let y = ballCenter.y + ballRadius; y < origin.y; y += chainLinkHeight) {
            ctx.beginPath();
            // Draw ovals for chain links
            ctx.ellipse(ballCenter.x, y, chainLinkWidth / 2, chainLinkHeight / 2, 0, 0, 2 * Math.PI);
            ctx.stroke();
        }
        
        // --- Draw Velocity Vector ---
        ctx.lineWidth = 2; 
        const velArrowStart = { x: ballCenter.x, y: ballCenter.y };
        const velArrowEnd = { x: ballCenter.x, y: ballCenter.y - 60 };
        ctx.beginPath();
        ctx.moveTo(velArrowStart.x, velArrowStart.y);
        ctx.lineTo(velArrowEnd.x, velArrowEnd.y);
        ctx.stroke();
        // Arrowhead
        ctx.beginPath();
        ctx.moveTo(velArrowEnd.x, velArrowEnd.y);
        ctx.lineTo(velArrowEnd.x - 5, velArrowEnd.y + 10);
        ctx.moveTo(velArrowEnd.x, velArrowEnd.y);
        ctx.lineTo(velArrowEnd.x + 5, velArrowEnd.y + 10);
        ctx.stroke();

        // --- Draw Dashed Line ---
        ctx.save(); // save current state
        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = '#555555';
        ctx.setLineDash([4, 4]);
        ctx.moveTo(ballCenter.x + ballRadius, ballCenter.y);
        ctx.lineTo(origin.x, ballCenter.y);
        ctx.stroke();
        ctx.restore(); // restore to previous state (solid line, black, etc.)

        // --- Draw Labels ---
        ctx.fillStyle = 'black';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // Label 'm'
        ctx.font = 'italic 22px "Times New Roman"';
        ctx.fillText('m', ballCenter.x - ballRadius - 15, ballCenter.y);

        // Label 'v'
        ctx.fillText('v', velArrowEnd.x + 20, velArrowEnd.y + 5);

        // Label 'x' (axis name)
        ctx.font = '22px "Times New Roman"';
        ctx.fillText('x', origin.x + 20, 55);

        // Label 'x' (position)
        ctx.save();
        ctx.globalAlpha = 0.8;
        ctx.font = '20px "Times New Roman"';
        ctx.fillText('x', origin.x - 20, ballCenter.y);
        ctx.restore();

        // Label 'O' (Origin)
        ctx.font = '20px "Times New Roman"';
        ctx.fillText('O', origin.x, origin.y + 20);

        // Caption
        // Use a font that supports Chinese characters, with fallback
        ctx.font = '22px "Song Ti", "SimSun", serif';
        const captionText = '力图 3.38.1';
        ctx.fillText(captionText, 225, 495);

    </script>
</body>
</html>